home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / net / parnet-3.2 / extras / parpc / amigafiles / sources / unit_dgr.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  4KB  |  192 lines

  1.  
  2. /*
  3.  *  UNIT_DGR.C            DATAGRAM PROTOCOL
  4.  */
  5.  
  6. #include "defs.h"
  7.  
  8. void DGramBeginIO(Iob *);
  9. void DGramAbortIO(Iob *);
  10. void DGramClose(Iob *);
  11. void DGramData(int, Packet *, long);
  12.  
  13. void UnitDGramOpen(Iob *, long, long);
  14.  
  15. /*
  16.  *  Called under Forbid
  17.  */
  18.  
  19. void
  20. UnitDGramOpen(iob, unitnum, flags)
  21. Iob *iob;
  22. long unitnum;
  23. long flags;
  24. {
  25.     Unit *unit;
  26.  
  27.     if (unit = FindUnitForPort(iob->io_Port)) {
  28.     if (unit->BeginIO != DGramBeginIO) {
  29.         iob->io_Error = PPERR_PORT_IN_USE;
  30.         return;
  31.     }
  32.     } else {
  33.     unit = AllocUnit(iob, DGramBeginIO, DGramAbortIO, DGramData, DGramClose);
  34.     }
  35.     iob->io_Unit = unit;
  36.     ++unit->RefCnt;
  37. }
  38.  
  39.  
  40. void
  41. DGramClose(iob)
  42. Iob *iob;
  43. {
  44.     Unit *unit = iob->io_Unit;
  45.  
  46.     if (--unit->RefCnt == 0) {
  47.     FreeUnit(unit);
  48.     }
  49.     iob->io_Unit = NULL;
  50. }
  51.  
  52. /*
  53.  *  UnitDGramData() is called whenever a low level network operation
  54.  *            completes for the given unit.  cmd is:
  55.  *
  56.  *            'r'     received data packet
  57.  *            'w'     wrote data packet
  58.  *            'W'     timeout writing data packet
  59.  *
  60.  *            The routine is called with the unix locked.
  61.  *
  62.  *  WARNING:    This call may not requeue synchronous packets, a lockout
  63.  *        will result.
  64.  */
  65.  
  66. void
  67. DGramData(cmd, packet, actual)
  68. int cmd;
  69. Packet *packet;
  70. long actual;    /*  'w', 'W'    */
  71. {
  72.     Unit *unit = packet->io_Unit;
  73.     Iob *iob = packet->iob;        /*    NULL for 'r'    */
  74.     long n;
  75.  
  76.     switch(cmd) {
  77.     case 'r':
  78.     sprintf(StickyPort->DebugBuf, " RDDRG %d",actual);
  79.  
  80.     if (iob = (Iob *)RemHead(&unit->PendIOR)) {
  81.         iob->io_Flags &= ~IOF_QUEUED;
  82.  
  83.         n = actual;
  84.         if (n < 0)
  85.         n = 0;
  86.         if (n > iob->io_Length) {
  87.         n = iob->io_Length;
  88.         iob->io_Error = PPERR_WARN_OVFLOW;
  89.         }
  90.         actual -= n;
  91.         movmem((char *)packet->Data1, (char *)iob->io_Data, n);
  92.  
  93.         if (iob->io_Length2 && actual > 0) {    /*  a second data buffer    */
  94.         if (actual > iob->io_Length2)
  95.             actual = iob->io_Length2;
  96.         movmem((char *)packet->Data1 + n, (char *)iob->io_Data2, actual);
  97.         n += actual;
  98.         }
  99.         iob->io_Actual = n;
  100.  
  101.         if ((iob->io_Flags & IOF_QUICK) == 0)
  102.         ReplyMsg(&iob->io_Message);
  103.     }
  104.  
  105.     /*
  106.      *  Note that if no read requests are pending the datagram is
  107.      *  thrown away.
  108.      */
  109.  
  110.     FreeParPacket(packet);
  111.     break;
  112.     case 'W':
  113.     sprintf(StickyPort->DebugBuf, " TMDRG %d",actual);
  114.  
  115.     Remove(iob);
  116.     iob->io_Flags &= ~IOF_QUEUED;
  117.     iob->io_Error = 1;
  118.     iob->io_Actual = actual;
  119.     if ((iob->io_Flags & IOF_QUICK) == 0)
  120.         ReplyMsg(&iob->io_Message);
  121.     FreeParPacket(packet);
  122.     break;
  123.     case 'w':
  124.     sprintf(StickyPort->DebugBuf, " WRDRG %d",actual);
  125.  
  126.     Remove(iob);
  127.     iob->io_Flags &= ~IOF_QUEUED;
  128.     iob->io_Actual = actual;
  129.     if ((iob->io_Flags & IOF_QUICK) == 0)
  130.         ReplyMsg(&iob->io_Message);
  131.     FreeParPacket(packet);
  132.     break;
  133.     }
  134. }
  135.  
  136. void
  137. DGramBeginIO(iob)
  138. Iob *iob;
  139. {
  140.     Unit *unit = iob->io_Unit;
  141.     Packet *packet;
  142.  
  143.     iob->io_Error = 0;
  144.     iob->io_Actual = 0;
  145.     iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  146.  
  147.     switch(iob->io_Command) {
  148.     case CMD_READ:
  149.     LockAddr(unit->UnitLock);
  150.     iob->io_Flags &= ~IOF_QUICK;
  151.     iob->io_Flags |= IOF_QUEUED;
  152.     AddTail(&unit->PendIOR, iob);
  153.     UnlockAddr(unit->UnitLock);
  154.     return;
  155.     case CMD_WRITE:
  156.     packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, iob->io_Data2, iob->io_Length2);
  157.     LockAddr(unit->UnitLock);
  158.     AddTail(&unit->PendIOW, iob);
  159.     UnlockAddr(unit->UnitLock);
  160.  
  161.     QueuePacketForWrite(packet);
  162.     return;
  163.     default:
  164.     CtlBeginIO(iob);
  165.     return;
  166.     }
  167. }
  168.  
  169. /*
  170.  *  Abort a read or write request.  Currently only read requests may be
  171.  *  aborted.
  172.  */
  173.  
  174. void
  175. DGramAbortIO(iob)
  176. Iob *iob;
  177. {
  178.     if (iob->io_Command == CMD_READ) {
  179.     LockAddr(iob->io_Unit->UnitLock);
  180.     if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
  181.         Remove(iob);
  182.         UnlockAddr(iob->io_Unit->UnitLock);
  183.         iob->io_Flags &= ~IOF_QUEUED;
  184.         iob->io_Error = -1;     /*    ??? */
  185.         ReplyMsg(&iob->io_Message);
  186.     } else {
  187.         UnlockAddr(iob->io_Unit->UnitLock);
  188.     }
  189.     }
  190. }
  191.  
  192.